/*
 * Copyright (c) 2009 by unreserved.org.
 * All rights reserved.
 */

package org.unreserved.ladderplot;

import java.util.NoSuchElementException;

/** 
 * 
 */
public class LabelTokenizer {
    private static final String[] NO_LINES = new String[0];
    
    /** Input lines broken up according to *forced* line breaks. */
    protected String[] forcedLines;
    
    /** Index into forcedLines. */
    protected int nextForced;
    
    /**
     * forcedLines[nextCurrent-1] broken up according to *optional*
     * line breaks.
     */
    protected String[] currentLine;
    
    /** Index into currentLine. */
    protected int nextCurrent;
    
    public LabelTokenizer(String input) {
        input = input.replace("\\\\", "\\");
        forcedLines = input.split("\\\\n");
        //System.out.println("<init>: forcedLines=" + toString(forcedLines));
        nextForced = 0;
        currentLine = NO_LINES;
        nextCurrent = 0;
    }
    
    private static String toString(String[] s) {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < s.length; i++) {
            if (i > 0) sb.append(',');
            sb.append("\"" + s[i] + "\"");
        }
        sb.append("]");
        return sb.toString();
    }
    
    public boolean hasNext() {
        return nextCurrent < currentLine.length ||
               nextForced < forcedLines.length;
    }
    
    public String nextToken() {
        if (nextCurrent < currentLine.length) {
            return currentLine[nextCurrent++];
        } else if (nextForced < forcedLines.length) {
            currentLine = forcedLines[nextForced++].split("\\\\-");
            //System.out.println("nextToken: currentLine=" + toString(currentLine));
            nextCurrent = 0;
            return currentLine[nextCurrent++];
        } else {
            throw new NoSuchElementException();
        }
    }
    
    /**
     * Returns true if there's a forced line break after the most
     * recently returned token.
     */
    public boolean forcedLineBreak() {
        //System.out.println("forcedLineBreak: " + nextForced + " " + nextCurrent);
        return nextCurrent >= currentLine.length &&
            nextForced > 0 &&
            nextForced < forcedLines.length;
    }
    
    
    ///////////////////////////////////////////////////////////////////////
    // unit testing (XXX: move to separate UT dir)
    
    public static void main(String[] args) {
        LabelTokenizer tok = new LabelTokenizer(args[0]);
        while (tok.hasNext()) {
            System.out.println("" + tok.nextToken() + "\t" +
                               tok.forcedLineBreak());
        }
    }
}
